package com.example.transactionhintassistant.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.transactionhintassistant.mapper.UsersMapper;
import com.example.transactionhintassistant.pojo.dto.auth.*;
import com.example.transactionhintassistant.pojo.entity.User;
import com.example.transactionhintassistant.pojo.vo.LoginVo;
import com.example.transactionhintassistant.service.AuthService;
import com.example.transactionhintassistant.service.RingtoneSelectionService;
import com.example.transactionhintassistant.utils.JwtHelper;
import com.example.transactionhintassistant.utils.MD5Util;
import com.example.transactionhintassistant.utils.result.Result;
import com.example.transactionhintassistant.utils.result.ResultCodeEnum;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Objects;

import static com.example.transactionhintassistant.pojo.constant.EmailConstant.*;

@Service
public class AuthServiceImpl extends ServiceImpl<UsersMapper, User>
        implements AuthService {
    @Autowired
    private JwtHelper jwtHelper;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private RingtoneSelectionService ringtoneSelectionService;
    private LambdaQueryWrapper<User> queryWrapper;

    @Override
    public Result<LoginVo> userRegister(RegisterDto registerDto) {
        if (!Objects.equals(registerDto.getPassword(), registerDto.getResetPassword())) {
            return Result.build(null, 500, "密码不一致");
        }
        //判断账号是否存在
        User user = getUserByAccount(registerDto.getAccount());
        if (user != null) {
            return Result.build(null, ResultCodeEnum.USERNAME_USED);
        }
        User user1 = new User();
        user1.setAccount(registerDto.getAccount());
        user1.setPassword(MD5Util.encrypt(registerDto.getPassword()));
        this.save(user1);

        User newUser = getUserByAccount(registerDto.getAccount());
        LoginVo loginVo = new LoginVo();
        loginVo.setToken(jwtHelper.createToken(newUser.getId()));
        new Thread(() -> {
            ringtoneSelectionService.addRingtoneSelection(newUser.getId());
        }).start();
        return Result.ok(loginVo, "成功创建新账号！");
    }

    @Override
    public Result<LoginVo> userLogin(LoginDto loginDto) {
        User loginUser = getUserByAccount(loginDto.getAccount());
        //账号判断
        if (loginUser == null) {
            return Result.build(null, ResultCodeEnum.USERNAME_ERROR);
        }
        //账号密码判断
        if (!StringUtils.isEmpty(loginDto.getPassword()) && loginUser.getPassword().equals(MD5Util.encrypt(loginDto.getPassword()))) {
            //账号密码正确
            //根据用户唯一标识生成token
            LoginVo loginVo = new LoginVo();
            loginVo.setToken(jwtHelper.createToken(loginUser.getId()));
            return Result.ok(loginVo);
        }
        //密码错误
        return Result.build(null, ResultCodeEnum.PASSWORD_ERROR);
    }

    @Override
    public Result<LoginVo> userLoginByEmail(EmailAndCaptchaDto emailAndCaptchaDto) {
        //账号查询
        User loginUser = getUserByEmail(emailAndCaptchaDto.getEmail());
        //账号判断
        if (loginUser == null) {
            return Result.build(null, ResultCodeEnum.LOGIN_EMAIL_ERROR);
        }
        String captcha = (String) redisTemplate.opsForValue().get(EMAIL_LOGIN_PRIM + emailAndCaptchaDto.getEmail());
        //账号密码判断
        if (captcha != null && !StringUtils.isEmpty(emailAndCaptchaDto.getCaptcha()) && captcha.equalsIgnoreCase(emailAndCaptchaDto.getCaptcha())) {
            //验证码正确
            //根据用户唯一标识生成token
            LoginVo loginVo = new LoginVo();
            loginVo.setToken(jwtHelper.createToken(loginUser.getId()));
            return Result.ok(loginVo);
        }
        //验证码错误
        return Result.build(null, ResultCodeEnum.CAPTCHA_ERROR);
    }

    @Override
    public Result<Object> changeUserPassword(ChangePwdDto changePwdDto) {
        //账号查询
        String token = request.getHeader("Authorization");
        int userId = jwtHelper.getUserId(token);
        User user = this.getById(userId);
        //账号密码判断
        if (!StringUtils.isEmpty(user.getPassword()) && user.getPassword().equals(MD5Util.encrypt(changePwdDto.getPassword()))) {
            //账号密码正确
            // 使用 LambdaUpdateWrapper 修改指定属性
            LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(User::getId, user.getId())
                    .set(User::getPassword, MD5Util.encrypt(changePwdDto.getNewPassword()));
            this.update(lambdaUpdateWrapper); // 执行更新操作
            return Result.ok(null, "修改成功！");
        }
        //密码错误
        return Result.build(null, ResultCodeEnum.PASSWORD_ERROR);
    }

    @Override
    public Result<Object> changeUserPwdByEmail(ChangePwdByEmailDto changePwdByEmailDto) {
        //账号查询
        User user = getUserByEmail(changePwdByEmailDto.getEmail());
        //账号判断
        if (user == null) {
            return Result.build(null, ResultCodeEnum.LOGIN_EMAIL_ERROR);
        }

        String captcha = (String) redisTemplate.opsForValue().get(EMAIL_CHANGE_PW_PRIM + changePwdByEmailDto.getEmail());
        //判断
        if (captcha != null && !StringUtils.isEmpty(changePwdByEmailDto.getCaptcha()) && captcha.equalsIgnoreCase(changePwdByEmailDto.getCaptcha())) {
            //验证码正确
            // 使用 LambdaUpdateWrapper 修改指定属性
            LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(User::getId, user.getId())
                    .set(User::getPassword, MD5Util.encrypt(changePwdByEmailDto.getNewPassword()));
            this.update(lambdaUpdateWrapper); // 执行更新操作
            return Result.ok(null, "修改成功！");
        }
        //验证码错误
        return Result.build(null, ResultCodeEnum.CAPTCHA_ERROR);
    }

    @Override
    public Result<Object> verifyOldEmail(EmailAndCaptchaDto emailAndCaptchaDto) {
        // 获取请求头中的令牌
        String token = request.getHeader("Authorization");
        int userId = jwtHelper.getUserId(token);
        User user = getUserByEmail(emailAndCaptchaDto.getEmail());
        if (user == null || userId != user.getId()) {
            return Result.build(null, ResultCodeEnum.ILLEGAL_OPERATION);
        }
        String captcha = (String) redisTemplate.opsForValue().get(EMAIL_CHANGE_EM_OLD_PRIM + emailAndCaptchaDto.getEmail());
        //判断
        if (captcha != null && !StringUtils.isEmpty(emailAndCaptchaDto.getCaptcha()) && captcha.equalsIgnoreCase(emailAndCaptchaDto.getCaptcha())) {
            return Result.ok(null, "旧邮箱验证成功！");
        }
        //验证码错误
        return Result.build(null, ResultCodeEnum.CAPTCHA_ERROR);
    }

    @Override
    public Result<Object> verifyNewEmail(ChangeEmailDto changeEmailDto) {
        // 获取请求头中的令牌
        String token = request.getHeader("Authorization");
        int userId = jwtHelper.getUserId(token);
        User user = getUserByEmail(changeEmailDto.getOldEmail());
        if (user == null || userId != user.getId()) {
            return Result.build(null, ResultCodeEnum.ILLEGAL_OPERATION);
        }

        String captcha = (String) redisTemplate.opsForValue().get(EMAIL_CHANGE_EM_NEW_PRIM + changeEmailDto.getEmail());
        //判断
        if (captcha != null && !StringUtils.isEmpty(changeEmailDto.getCaptcha()) && captcha.equalsIgnoreCase(changeEmailDto.getCaptcha())) {
            if (changeEmailDto.getEmail().equals(changeEmailDto.getOldEmail())) {
                return Result.build(null, 500, "当前的新旧邮箱相同");
            }

            LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(User::getId, userId)
                    .set(User::getEmail, changeEmailDto.getEmail());
            this.update(updateWrapper);
            return Result.ok(null, "新邮箱修改成功！");
        }
        //验证码错误
        return Result.build(null, ResultCodeEnum.CAPTCHA_ERROR);
    }

    @Override
    public Result<Object> bindingEmail(EmailAndCaptchaDto emailAndCaptchaDto) {
        queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getEmail, emailAndCaptchaDto.getEmail());
        if (this.exists(queryWrapper)) {
            return Result.build(null, ResultCodeEnum.EMAIL_USED);
        }

        String captcha = (String) redisTemplate.opsForValue().get(EMAIL_BINDING_EM_PRIM + emailAndCaptchaDto.getEmail());
        //判断
        if (captcha != null && !StringUtils.isEmpty(emailAndCaptchaDto.getCaptcha()) && captcha.equalsIgnoreCase(emailAndCaptchaDto.getCaptcha())) {
            // 获取请求头中的令牌
            String token = request.getHeader("Authorization");
            int userId = jwtHelper.getUserId(token);
            LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(User::getId, userId)
                    .set(User::getEmail, emailAndCaptchaDto.getEmail());
            this.update(updateWrapper);
            return Result.ok(null, "邮箱成功绑定！");
        }
        //验证码错误
        return Result.build(null, ResultCodeEnum.CAPTCHA_ERROR);
    }

    public User getUserByAccount(String account) {
        queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getAccount, account);
        return this.getOne(queryWrapper);
    }

    public User getUserByEmail(String email) {
        queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getEmail, email);
        return this.getOne(queryWrapper);
    }

}
